package agataMeble.inspiration.browser 
{
	import com.greensock.easing.Back;
	import com.greensock.easing.Quad;
	import com.greensock.easing.Quint;
	import com.greensock.TweenMax;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.setTimeout;
	import flash.utils.Timer;
	import msz.framework.events.PagesEvent;
	/**
	 * ...
	 * @author Bartłomiej JERZY
	 */
	public class Palette extends Sprite
	{
		private var DIFF							:Number = 0.029
		private var  NUM							:Number = 0
		private const UP_LIMIT						:Number = .79
		private const DN_LIMIT						:Number = 0.58
		private const CENTER						:Number = (DN_LIMIT+UP_LIMIT)/2
		private const AIM							:Number = 0.65
		private const ALPHA_SPEED					:Number = 50
		private var HIDE_ZONE						:Number = 1/ALPHA_SPEED
		
		private var _cont							:Sprite = new Sprite()
			
		private var _timer							:Timer = new Timer(5000)
		
		
		private var _items							:Array = []
		private var _curr							:Leaf
		private var _currNum						:int = 0
	
		private var _mid							:int
		private var _wheel							:Boolean = true
		private var _auto 							:Boolean = false
		
	
		private var _data							:Object
		private var _speed							:Number ;
	
		public function Palette($data:Object) 
		{
			_data =  $data
			NUM = _data.length
					
			addEventListener(Event.ADDED_TO_STAGE,addedToStage,false,0,true)
		}
		
		private function addedToStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
			initPalettes()
		}
		
		private function initPalettes():void {
				
			initItems()
			//initEvents()
			
			
			
			//_timer.start()
		}
		
		private function initEvents():void
		{
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler, false, 0, true)
			_timer.addEventListener(TimerEvent.TIMER, onTimer)
			dispatchEvent(new Event(Event.SELECT))
		}
		
		private function onTimer(e:TimerEvent):void 
		{
			_auto = true
		}
		
		private function mouseWheelHandler(e:MouseEvent):void 
		{
			if (_wheel) {
				_wheel = false
				if (e.delta > 0) {
					next()
				}else {
					prev()
				}
				setTimeout(function():void{_wheel = true},50)
			}
		}
				
		private function next(e:Event = null):void {
			//_timer.reset()
			//_timer.start()
			_auto = false
			select(_curr.n)
		}
		
		private function prev(e:Event = null):void {
			//_timer.reset()
			//_timer.start()
			_auto = false
			select(_curr.p)
		}
				
		private function initItems():void {
			
			
			var num:int = Math.floor(1/DIFF);
			var n:int = NUM;
			while (n<num) {
				n += NUM;
			}
			var j:int = 0;

			for (var i:int = 0; i < n; i++) {
				
				
				_items[i] = new Leaf(_data[i%NUM].projects[0])
				_items[i].y = 300
				_items[i].t = 0.5 + DIFF * i - (n - 1) * DIFF / 2//1-DIFF*i-3
				_items[i].addEventListener(Event.SELECT,itemSelected)
				_items[i].id = i%NUM
				
				
				j++
				
				if ((i % NUM == 0 && i>0) || NUM ==1) {
					 j=0	
				}
				
				
				
				if(i>0){
					_items[i - 1].n = _items[i]
					_items[i].p = _items[i - 1]
				}
			}
			
			
			
			_items[0].p = _items[_items.length-1]
			_items[_items.length - 1].n = _items[0]
			
			_curr = _items[0]
			_curr.t = AIM
			_curr.selected = true
			_speed = 1
			
			_cont.addChild(_curr)
			update()
			
			//select(_curr)
			
			_cont.y = -50
			
			addChild(_cont)
			
			show()
		}
		
		private function show():void
		{
			for (var i:int = 0; i < _cont.numChildren; i++) 
			{
				var _child:Leaf = _cont.getChildAt(i) as Leaf
				if (i) {
					TweenMax.from(_child,0.4,{rotation:-90,delay:0.4})
				}else {
					TweenMax.from(_child,0.4,{rotation:-90,onComplete:initEvents,delay:0.4})
				}
			}
			TweenMax.from(this,0.4,{y:1000,ease:Quad.easeOut})
			
		}
		
		private function itemSelected(e:Event):void 
		{
			select(e.currentTarget as Leaf)
			
		}
		
		private function select($item:Leaf):void {
			
			TweenMax.killTweensOf(_curr)
			
			_curr.selected = false
			_curr = $item
			_curr.selected = true
			
			if (_curr.t < AIM) {
				_speed = 1
			}else {
				_speed = -1
			}
			
			
			_cont.setChildIndex(_curr, _cont.numChildren - 1)
			
			TweenMax.to(_curr, 0.3 + Math.abs(_curr.t - AIM) * 3, { t:AIM, onUpdate:update, ease:Quad.easeOut } )
			
			dispatchEvent(new Event(Event.SELECT))
		}
		
		private function update(e:Event=null):void 
		{
			//position()
			updatePosition()
			fix()
			render()
			
		}
		
		private function fix():void
		{
			if (_speed>0) {
				
				_mid = Math.round(_items.length / 2);
				
				while (_items[_mid].t > CENTER) {
					_items[_items.length-1].t = _items[0].t-DIFF;
					_items.splice(0,0,_items[_items.length-1]);
					_items.pop();
					
					_mid = Math.round(_items.length / 2);
				}
			} else {
				
				_mid = Math.round(_items.length/2)-1;
				
				while (_items[_mid].t < CENTER) {
					
					_items[0].t = _items[_items.length-1].t+DIFF;
					_items.push(_items[0]);
					_items.splice(0, 1);
					
					_mid = Math.round(_items.length/2)-1;
				}
			}
		}
		
		private function position():void {
		
			if (_auto) {
				_speed = 0.001
				if (AIM - _curr.t<0) _curr = _curr.n
			}else {
				_speed = (AIM - _curr.t) / 10	
			}
			
			
			for (var i:int = 0; i < _items.length; i++) {
				_items[i].t += _speed
				
			}
		
		}
		
		private function updatePosition():void {
			_currNum = _items.indexOf(_curr)
			for (var i:int = 0; i < _items.length; i++) {
				if (i < _currNum) {
					_items[i].t = _curr.t- (_currNum-i)*DIFF
				}else if (i>_currNum){
					_items[i].t = _curr.t+ (i-_currNum)*DIFF
				}
				
			}
		}
		private function render():void {
		
			for (var i:int = 0; i < _items.length; i++) {
				if(_items[i].t >=DN_LIMIT-HIDE_ZONE && _items[i].t <= UP_LIMIT+HIDE_ZONE){
					if (!_cont.contains(_items[i])) {
						_cont.addChild(_items[i])
					}
					TweenMax.to(_items[i],0.3,{alpha:1})
					
					_cont.setChildIndex(_items[i], _cont.numChildren - 2)
					_cont.setChildIndex(_curr, _cont.numChildren - 1)
					
				}else {
				
					TweenMax.to(_items[i], 0.15, { alpha:0, onComplete:removeItem,onCompleteParams:[_items[i]]} )
				}
				_items[i].rotation = _items[i].t * 360
				/*if ( _items[i].t > UP_LIMIT ) {
					_items[i].alpha = 1-(_items[i].t-UP_LIMIT)*ALPHA_SPEED
				}else if ( _items[i].t  < DN_LIMIT) {
					_items[i].alpha = 1-(DN_LIMIT-_items[i].t)*ALPHA_SPEED
				}else if (_items[i].t > DN_LIMIT && _items[i].t < UP_LIMIT){
					_items[i].alpha = 1
				}*/
				
			}
		}
		
		private function removeItem($i:Leaf):void {
			if (_cont.contains($i))  { 
				_cont.removeChild($i)
			}
				
		}
		
		public function hideAndClear():void {
			for (var i:int = 0; i < _cont.numChildren; i++) 
			{
				var _child:Leaf = _cont.getChildAt(i) as Leaf
				if (i) {
					TweenMax.to(_child,0.5,{rotation:-90,delay:0.4})
				}else {
					TweenMax.to(_child,0.5,{rotation:-90,delay:0.4})
				}
			}
			TweenMax.to(this,0.6,{y:1000,ease:Back.easeIn,delay:0.4,onComplete:destroy})
		}
		
		public function destroy():void {
			dispatchEvent(new PagesEvent(PagesEvent.ON_CLEAR))
		}
		
		public function get curr():int { 
			return _curr.id; 
		}
		
		
	}
}